﻿#include "CDeviceManager.h"
#include <QMessageBox>
#include <QCoreApplication>
#include <QDir>
#include <QFileInfo>
#include <QStringList>
#include <QDebug>
#include "Global.h"
#include "UBindDevice.h"
CDeviceManager::CDeviceManager(QObject* parent) : QObject(parent), currentDevice(nullptr) 
{
	loadConfig();
}

bool CDeviceManager::loadConfig()
{
	// 获取当前程序路径
	QString exePath = QCoreApplication::applicationDirPath();
	// 构造 DLL 文件路径
	QString dllPath = exePath + "/DLL/" + "Dllconfig.cfg";

	QFile file(dllPath);
	if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
	{
		return false;
	}

	QTextStream in(&file);
	// 跳过标题行
	if (!in.atEnd()) {
		in.readLine();
	}

	while (!in.atEnd()) {
		QString line = in.readLine().trimmed();
		if (line.isEmpty()) {
			continue;
		}
		QStringList sList = line.split(',');
		if (sList.size() >= 2)
		{
			g_mapDllName.insert(sList[1], sList[0]);
			g_mapNameDll.insert(sList[0], sList[1]);
		}
	}

	file.close();
	return true;
}

void CDeviceManager::setCardQss(QVector<QWidget*> vecWidget)
{
	for (int i = 0; i < vecWidget.size(); i++)
	{
		QString sMyqss = vecWidget[i]->styleSheet();
		QString merged = getCardQss() + "\n" + sMyqss; // 后面的会覆盖前面的相同规则
		vecWidget[i]->setStyleSheet(merged);
	}

}

CBaseDevice * CDeviceManager::getDevice(QString sName, QString sId, QString sConfig, QObject * parent)
{
	QStringList sList = sConfig.split("-");
	if (sList.size() <2)
	{
		return nullptr;
	}
	if (!g_mapNameDll.contains(sList[0]))
	{
		return nullptr;
	}
	CBaseDevice *pBaseDevice = new CBaseDevice(sName, sId, sConfig, (CBaseNode *)parent);
	createDeviceInstance(pBaseDevice);
	return pBaseDevice;
}

QVector<CBaseDevice*> CDeviceManager::createDevices(QString sName, QString sConfig, QObject* parent)
{
	return createDevicesInstance(sName, sConfig, (CBaseNode*)parent);
}


QMenu* CDeviceManager::createDeviceMenu(CBaseDevice* device, QWidget* parent) {
	currentDevice = device;
	QMenu* menu = new QMenu(A2T("设备操作"), parent);
	menu->addAction(A2T("运行"), this, SLOT(onRunDevice()));
	menu->addAction(A2T("停止"), this, SLOT(onStopDevice()));
	menu->addAction(A2T("重命名设备"), this, SLOT(onRenameDevice()));
	menu->addAction(A2T("报警使能"), this, SLOT(onEnableAlarm()));
	return menu;
}

QVector<QString> CDeviceManager::getDllListFromPath()
{
	// 获取 exe 所在路径
	QString exeDirPath = QCoreApplication::applicationDirPath();

	// 拼接 DLL 子目录路径
	QDir dllDir(exeDirPath + "/DLL");

	QVector<QString> vecDllFiles;
	if (!dllDir.exists()) {
		qWarning("DLL directory does not exist: %s", qPrintable(dllDir.path()));
		return vecDllFiles;
	}

	// 过滤 *.dll 文件
	QStringList filters;
	filters << "*.dll";
	dllDir.setNameFilters(filters);
	dllDir.setFilter(QDir::Files | QDir::NoSymLinks);

	QFileInfoList fileList = dllDir.entryInfoList();
	for (const QFileInfo& fileInfo : fileList) {
		vecDllFiles.push_back(fileInfo.completeBaseName());
	}

	return vecDllFiles;
}

QVector<QString> CDeviceManager::getModelList(QString sDllName)
{
	QVector<QString> vecMode;
	if (m_mapDll.contains(sDllName))
	{
		QVector<QString> *pPtr = m_mapDll[sDllName].getModelListFunc();
		if (pPtr != NULL)
			vecMode = *pPtr;
		//vecMode = *m_mapDll[sDllName].getModelListFunc();
	}
	else
	{
		if (loadLibrary(sDllName))
		{
			QVector<QString> *pPtr = m_mapDll[sDllName].getModelListFunc();
			if(pPtr!=NULL)
				vecMode = *pPtr;
		}
	}
	return vecMode;
}



// 根据设备名称加载 DLL 并缓存其 create/destroy 函数
bool CDeviceManager::loadLibrary(const QString& deviceName)
{
	// 获取当前程序路径
	QString exePath = QCoreApplication::applicationDirPath();
	// 构造 DLL 文件路径
	QString dllPath = QDir(exePath).filePath("dll") + "/" + deviceName + ".dll";

	if (m_mapDll.contains(deviceName)) return true; // 已加载

	QLibrary* lib = new QLibrary(dllPath);
	if (!lib->load()) 
	{
		QString sErr= A2T("DLL 加载失败:") +lib->errorString();
		delete lib;
		return false;
	}

	// 解析 DLL 中的函数
	LoadedLibrary::CreateDeviceFunc createFunc = (LoadedLibrary::CreateDeviceFunc)lib->resolve("createDevice");
	LoadedLibrary::CreateDevicesFunc createFuncs = (LoadedLibrary::CreateDevicesFunc)lib->resolve("createDevices");
	LoadedLibrary::DestroyDeviceFunc destroyFunc = (LoadedLibrary::DestroyDeviceFunc)lib->resolve("destroyDevice");
	LoadedLibrary::GetModelListFunc getModelListFunc = (LoadedLibrary::GetModelListFunc)lib->resolve("getModelList");

	if (!createFunc || !destroyFunc || !getModelListFunc|| !createFuncs) {
		qWarning() << "函数解析失败";
		lib->unload();
		delete lib;
		return false;
	}

	// 缓存 DLL 信息
	LoadedLibrary loaded;
	loaded.dllPath = dllPath;
	loaded.library = lib;
	loaded.createFunc = createFunc;
	loaded.createFuncs = createFuncs;
	loaded.destroyFunc = destroyFunc;
	loaded.getModelListFunc = getModelListFunc;

	m_mapDll.insert(deviceName, loaded);
	return true;
}

IDevice * CDeviceManager::createDeviceInstance(CBaseDevice * pBaseDevice)
{
	IDevice *pDevice = nullptr;
	if (!m_mapDll.contains(pBaseDevice->getDllName()))
	{
		if (!loadLibrary(pBaseDevice->getDllName()))
		{
			return nullptr;
		}		
	}
	SDeviceConfig *pDeviceConfig = new SDeviceConfig();
	pDeviceConfig->sConfig = pBaseDevice->getConfig();
	pDeviceConfig->sDeviceId = pBaseDevice->getId();
	pDeviceConfig->sDeviceName = pBaseDevice->getName();
	UBindDevice* pBindDevice = new UBindDevice();
	pDeviceConfig->pWidget = pBindDevice;
	pDevice = m_mapDll[pBaseDevice->getDllName()].createFunc(pDeviceConfig);
	if (pDevice != nullptr)
	{
		setBaseDevice(pBaseDevice, pDevice);
	}
	return pDevice;
}

QVector<CBaseDevice*> CDeviceManager::createDevicesInstance(QString sName, QString sConfig, QObject* parent)
{
	QVector<CBaseDevice*>vecBaseDevice;
	QStringList sList = sConfig.split("-");
	QString sDllName = "";
	if (sList.size() <= 0)
	{
		return vecBaseDevice;
	}
	sDllName = sList[0];
	if (!m_mapDll.contains(sDllName))
	{
		if (!loadLibrary(sDllName))
		{
			return vecBaseDevice;
		}
	}
	SDeviceConfig* pDeviceConfig = new SDeviceConfig();
	pDeviceConfig->sConfig = sConfig;
	pDeviceConfig->sDeviceId = generateUniqueId("Dev");
	pDeviceConfig->sDeviceName = sName;
	UBindDevice* pBindDevice = new UBindDevice();
	pDeviceConfig->pWidget = pBindDevice;
	auto pVec = m_mapDll[sDllName].createFuncs(pDeviceConfig);
	if (!pVec)
	{
		return vecBaseDevice;
	}
	QVector<IDevice*>vecDevice = *pVec;
	for (int i = 0; i < vecDevice.size(); i++)
	{
		CBaseDevice* pBaseDevice = new CBaseDevice(vecDevice[i]->m_pDeviceConfig->sDeviceName, vecDevice[i]->m_pDeviceConfig->sDeviceId, sConfig, (CBaseNode*)parent);
		setBaseDevice(pBaseDevice, vecDevice[i]);
		vecBaseDevice.push_back(pBaseDevice);
		pBaseDevice->init();  //初始化
	}
	return vecBaseDevice;
}

void CDeviceManager::setBaseDevice(CBaseDevice* pBaseDevice, IDevice* pDevice)
{
	pBaseDevice->setDevice(pDevice);
	/**
	* @ Author: Gaojia
	* @ Description: 获取类型和对应的名称
	*/
	QVector<QString>vecTypeName = *m_mapDll[pBaseDevice->getDllName()].getModelListFunc();
	QMap<int, QString>mapTypeName;
	for (int i = 0; i < vecTypeName.size(); i++)
	{
		mapTypeName.insert(i, vecTypeName[i]);
	}
	m_mapTypeName.insert(pBaseDevice->getDllName(), mapTypeName);
	/**
	* @ Author: Gaojia
	* @ Description:  初始化全局缩略图数组g_mapCardWidget
	*/
	if (!g_mapCardWidget.contains(pBaseDevice->getDllName()))
	{
		QMap<int, SDeviceWidget>mapDeviceWidget;
		SDeviceWidget cDeviceWidget;
		cDeviceWidget.sDllNameCh = g_mapNameDll[pBaseDevice->getDllName()];
		cDeviceWidget.sDllName = pBaseDevice->getDllName();
		cDeviceWidget.nDeviceType = pBaseDevice->getDeviceType();
		cDeviceWidget.vecWidget = pDevice->getDeviceUiList();
		
		setCardQss(cDeviceWidget.vecWidget);
		cDeviceWidget.sTypeName = m_mapTypeName[pBaseDevice->getDllName()][pBaseDevice->getDeviceType()];
		mapDeviceWidget.insert(pBaseDevice->getDeviceType(), cDeviceWidget);
		g_mapCardWidget.insert(pBaseDevice->getDllName(), mapDeviceWidget);
	}
	if (!g_mapCardWidget[pBaseDevice->getDllName()].contains(pBaseDevice->getDeviceType()))
	{
		SDeviceWidget cDeviceWidget;
		cDeviceWidget.sDllNameCh = g_mapNameDll[pBaseDevice->getDllName()];
		cDeviceWidget.sDllName = pBaseDevice->getDllName();
		cDeviceWidget.nDeviceType = pBaseDevice->getDeviceType();
		cDeviceWidget.vecWidget = pDevice->getDeviceUiList();
		setCardQss(cDeviceWidget.vecWidget);
		cDeviceWidget.sTypeName = m_mapTypeName[pBaseDevice->getDllName()][pBaseDevice->getDeviceType()];
		g_mapCardWidget[pBaseDevice->getDllName()].insert(pBaseDevice->getDeviceType(), cDeviceWidget);
	}
}



bool CDeviceManager::destroyDeviceInstance(IDevice * device)
{
	return false;
}

void CDeviceManager::destroyDevicesByDll(const QString & dllName)
{
}

void CDeviceManager::unloadAllDevices()
{
}

void CDeviceManager::onRunDevice() {
	QMessageBox::information(nullptr, "运行", currentDevice->getName() + " 设备运行");
}

void CDeviceManager::onStopDevice() {
	QMessageBox::information(nullptr, "停止", currentDevice->getName() + " 设备停止");
}

void CDeviceManager::onRenameDevice() {
	QMessageBox::information(nullptr, "重命名", "可在主界面实现重命名");
}

void CDeviceManager::onEnableAlarm() {
	QMessageBox::information(nullptr, "报警", currentDevice->getName() + " 报警已使能");
}
